/**
 * 数据验证函数
 * 提供文档数据的验证和规范化功能
 */

import type { Document, CreateDocumentInput, UpdateDocumentInput } from '../../types/document'

/**
 * 验证结果接口
 */
export interface ValidationResult {
  isValid: boolean
  errors: string[]
  warnings: string[]
}

/**
 * 验证文档标题
 */
export const validateTitle = (title: string): string[] => {
  const errors: string[] = []

  if (!title || title.trim().length === 0) {
    errors.push('文档标题不能为空')
  }

  if (title && title.length > 200) {
    errors.push('文档标题不能超过200个字符')
  }

  if (title && title.includes('\n')) {
    errors.push('文档标题不能包含换行符')
  }

  return errors
}

/**
 * 验证文档内容
 */
export const validateContent = (content: string): string[] => {
  const errors: string[] = []

  if (content && content.length > 1000000) {
    errors.push('文档内容不能超过100万个字符')
  }

  return errors
}

/**
 * 验证文档ID
 */
export const validateDocumentId = (id: string): string[] => {
  const errors: string[] = []

  if (!id || id.trim().length === 0) {
    errors.push('文档ID不能为空')
  }

  if (id && !id.match(/^doc_[a-z0-9_]+$/)) {
    errors.push('文档ID格式不正确，应以doc_开头，只包含小写字母、数字和下划线')
  }

  if (id && id.length > 100) {
    errors.push('文档ID长度不能超过100个字符')
  }

  return errors
}

/**
 * 验证创建文档输入
 */
export const validateCreateDocumentInput = (input: CreateDocumentInput): ValidationResult => {
  const errors: string[] = []
  const warnings: string[] = []

  // 验证标题
  errors.push(...validateTitle(input.title))

  // 验证内容（可选）
  if (input.content) {
    errors.push(...validateContent(input.content))
    
    if (input.content.trim().length === 0) {
      warnings.push('文档内容为空')
    }
  } else {
    warnings.push('未提供文档内容，将创建空文档')
  }

  return {
    isValid: errors.length === 0,
    errors,
    warnings
  }
}

/**
 * 验证更新文档输入
 */
export const validateUpdateDocumentInput = (input: UpdateDocumentInput): ValidationResult => {
  const errors: string[] = []
  const warnings: string[] = []

  // 检查是否至少提供了一个字段
  if (!input.title && input.content === undefined) {
    errors.push('必须至少提供标题或内容中的一个字段进行更新')
  }

  // 验证标题（如果提供）
  if (input.title !== undefined) {
    errors.push(...validateTitle(input.title))
  }

  // 验证内容（如果提供）
  if (input.content !== undefined) {
    errors.push(...validateContent(input.content))
    
    if (input.content.trim().length === 0) {
      warnings.push('文档内容将被清空')
    }
  }

  return {
    isValid: errors.length === 0,
    errors,
    warnings
  }
}

/**
 * 验证完整文档
 */
export const validateDocument = (doc: Partial<Document>): ValidationResult => {
  const errors: string[] = []
  const warnings: string[] = []

  // 验证ID（如果提供）
  if (doc.id) {
    errors.push(...validateDocumentId(doc.id))
  }

  // 验证标题
  if (doc.title !== undefined) {
    errors.push(...validateTitle(doc.title))
  } else {
    errors.push('文档必须包含标题')
  }

  // 验证内容
  if (doc.content !== undefined) {
    errors.push(...validateContent(doc.content))
  }

  // 验证时间字段
  if (doc.createdAt && !(doc.createdAt instanceof Date)) {
    errors.push('创建时间必须是有效的Date对象')
  }

  if (doc.updatedAt && !(doc.updatedAt instanceof Date)) {
    errors.push('更新时间必须是有效的Date对象')
  }

  if (doc.createdAt && doc.updatedAt && doc.createdAt > doc.updatedAt) {
    errors.push('创建时间不能晚于更新时间')
  }

  return {
    isValid: errors.length === 0,
    errors,
    warnings
  }
}

/**
 * 规范化文档数据
 * 清理和格式化文档数据
 */
export const normalizeDocument = (doc: Document): Document => {
  return {
    ...doc,
    title: doc.title.trim(),
    content: doc.content || '',
    createdAt: new Date(doc.createdAt),
    updatedAt: new Date(doc.updatedAt)
  }
}

/**
 * 规范化创建文档输入
 */
export const normalizeCreateDocumentInput = (input: CreateDocumentInput): CreateDocumentInput => {
  return {
    title: input.title.trim(),
    content: input.content?.trim() || ''
  }
}

/**
 * 规范化更新文档输入
 */
export const normalizeUpdateDocumentInput = (input: UpdateDocumentInput): UpdateDocumentInput => {
  const normalized: UpdateDocumentInput = {}

  if (input.title !== undefined) {
    normalized.title = input.title.trim()
  }

  if (input.content !== undefined) {
    normalized.content = input.content.trim()
  }

  return normalized
}
